﻿namespace FrontEnd.Application.MembershipFacade.Implementation
{
	using System;
	using AutoMapper;
	using Models;
	using Core.Domain;
	using System.Diagnostics.Contracts;
	using RegistrationResult=Models.RegistrationResult;

	internal class DefaultMembershipFacade : IMembershipFacade
	{

		public DefaultMembershipFacade(IAccountRepository accountRepository, RegistrationService registrationService)
		{
			CodeContract.Requires(accountRepository != null);
			CodeContract.Requires(registrationService != null);
			this.AccountRepository = accountRepository;
			this.RegistrationService = registrationService;		
		}

		public IAccountRepository AccountRepository
		{
			get; 
			private set;
		}

		public RegistrationService RegistrationService
		{
			get;
			private set;
		}

		public RegistrationResult Register(string email, string displayName, string password)
		{
			var result = this.RegistrationService.Register(email, displayName, password);
			if (result.Code == RegistrationResultCode.Success)
			{
				AccountInfo accountInfo = MapAccountToInfo(result.Account);

				CodeContract.Ensures(CodeContract.Result<RegistrationResult>() != null);
				CodeContract.Ensures(CodeContract.Result<RegistrationResult>().Person != null);

				return new RegistrationResult
				       	{
				       		IsSuccess = true,
				       		Person = accountInfo.Person
				       	};
			}
			return new RegistrationResult {IsSuccess = false};
		}		

		public AuthenticationResult Authenticate(string email, string password)
		{
			throw new NotImplementedException();
		}

		#region Utility

		private static AccountInfo MapAccountToInfo(Account account)
		{
			return CreateMapper().Map<Account, AccountInfo>(account);
		}

		private static IMappingEngine CreateMapper()
		{
			return new MappingEngine(CreateMapperConfiguration());
		}

		public static IConfiguration CreateMapperConfiguration()
		{
			Configuration configuration = new Configuration();

			configuration.CreateMap<Account, AccountInfo>();
			configuration.CreateMap<Person, PersonInfo>();

			return configuration;
		}

		#endregion
	}
}
